package com.tf_cut.backend.payment.service.impl;

import com.bill99.asap.exception.CryptoException;
import com.bill99.asap.service.ICryptoService;
import com.bill99.asap.service.impl.CryptoServiceFactory;
import com.bill99.schema.asap.commons.Mpf;
import com.bill99.schema.asap.data.SealedData;
import com.bill99.schema.asap.data.UnsealedData;
import com.tf_cut.backend.agent.vo.AgentCashOrderVo;
import com.tf_cut.backend.mapper.AgentCashMapper;
import com.tf_cut.backend.mapper.GrantDetailMapper;
import com.tf_cut.backend.mapper.SellerOrderMapper;
import com.tf_cut.backend.payment.paydto.Pay2bankOrder;
import com.tf_cut.backend.payment.paydto.Pay2bankRequest;
import com.tf_cut.backend.payment.paydto.Pay2bankResponse;
import com.tf_cut.backend.payment.service.PaymentService;
import com.tf_cut.backend.platform.vo.GrantDetailVo;
import com.tf_cut.backend.seller.service.SellerServiceImpl;
import com.tf_cut.backend.util.*;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.StringRequestEntity;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import javax.net.ssl.SSLContext;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.UnsupportedEncodingException;
import java.math.BigDecimal;
import java.util.List;

@Service
@Transactional
public class PaymentServiceImpl implements PaymentService {
    private Logger logger = LogManager.getLogger(SellerServiceImpl.class);
    @Autowired
    private SellerOrderMapper sellerOrderMapper;

    @Autowired
    private AgentCashMapper orderMapper;

    @Resource
    private ConfigSettingUtil configUtil;

    @Resource
    private MD5Util md5Util;

    @Autowired
    private GrantDetailMapper grantDetailMapper;


    @Autowired
    private AgentCashMapper agentCashMapper;

    @Autowired
    private LLPayUtil llPayUtil;


    @Override
    public int paymentSellerProvide(String orderId) throws Exception {
        /*
        已经为线上支付订单，无需再查看支付开关
        String isPayment = configUtil.getConfigValue("payment","is_payment");    //支付开关

        //支付接口已关闭
        if("off".equals(isPayment)){
            return 9;
        }
         */
        GrantDetailVo vo = new GrantDetailVo();
        vo.setOrderId(orderId);
        List<GrantDetailVo> list = grantDetailMapper.queryGrantDetailList(vo);

        for(GrantDetailVo detail : list){
            if("O".equals(detail.getPaymentStatus())){
                logger.info("发放详单：" + detail.getId() + "支付中：");
//                paymentByDetail(detail);
                llPayUtil.pay(detail);
                logger.info("发放详单：" + detail.getId() + "支付完成.");
            }
        }
        return 0;
    }


    @Override
    public int paymentAgentCash(AgentCashOrderVo agentCashOrderVo) throws Exception {
         /*
        已经为线上支付订单，无需再查看支付开关
        String isPayment = configUtil.getConfigValue("payment","is_payment");    //支付开关

        //支付接口已关闭
        if("off".equals(isPayment)){
            return 9;
        }
        */
        if("O".equals(agentCashOrderVo.getPaymentStatus())) {
            logger.info("提现订单：" + agentCashOrderVo.getOrderId() + "支付中：");
            paymentByCash(agentCashOrderVo);
            logger.info("提现订单：" + agentCashOrderVo.getOrderId() + "支付完成.");
        }
        return 0;
    }


    private void updateDetail(GrantDetailVo detail,String sealMsg,String fetureCode ,String membercode){
        logger.info("应答密文: " + sealMsg);
        Pay2bankResponse response = CCSUtil_Pay.converyToJavaBean(sealMsg, Pay2bankResponse.class);

        String respCode = response.getResponseBody().getErrorCode();
        String respMsg = response.getResponseBody().getErrorMsg();
        //解密应答报文
        SealedData sealedData = new SealedData();
        sealedData.setOriginalData(response.getResponseBody().getSealDataType().getOriginalData()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getOriginalData()));
        sealedData.setSignedData(response.getResponseBody().getSealDataType().getSignedData()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getSignedData()));
        sealedData.setEncryptedData(response.getResponseBody().getSealDataType().getEncryptedData()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getEncryptedData()));
        sealedData.setDigitalEnvelope(response.getResponseBody().getSealDataType().getDigitalEnvelope()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getDigitalEnvelope()));
        Mpf mpf = genMpf(fetureCode , membercode);
        UnsealedData unsealedData = null;

        try {

            ICryptoService service = CryptoServiceFactory.createCryptoService();
            unsealedData = service.unseal(mpf, sealedData);

            byte[] decryptedData = unsealedData.getDecryptedData();
            String rtnString = "";
            if (null != decryptedData) {
                rtnString = PKIUtil.byte2UTF8String(decryptedData);
            } else {
                rtnString = PKIUtil.byte2UTF8String(sealedData.getOriginalData());
            }
            logger.info("解密后返回报文: " + rtnString);

            Pay2bankOrder respOrder = CCSUtil_Pay.converyToJavaBean(rtnString,Pay2bankOrder.class);

            if(detail.getId().equals(respOrder.getOrderId())){
                //支付请求成功
                if(respCode.equals("0000")){
                    //P处理中 S成功  F失败
                    detail.setPaymentStatus("P");
                    detail.setPaymentMsg("银行处理中");
                }else{
                    detail.setPaymentStatus("F");
                    detail.setPaymentMsg(respMsg);
                }

                grantDetailMapper.updateGrantDetailByPayment(detail);
            }
        } catch (CryptoException e) {
            logger.error("解密失败：",e);
            detail.setPaymentMsg("解密失败，请稍后发起查询");
            //P处理中 S成功  F失败
            detail.setPaymentStatus("P");
            //解密失败，需重新发起查询更新状态
            grantDetailMapper.updateGrantDetailByPayment(detail);
        }
        //将订单加入查询队列
        QueryPaymentQueue.set(detail);
    }

    private void updateCash(AgentCashOrderVo agentCashOrderVo,String sealMsg,String fetureCode ,String membercode){
        logger.info("应答密文: " + sealMsg);
        Pay2bankResponse response = CCSUtil_Pay.converyToJavaBean(sealMsg, Pay2bankResponse.class);

        String respCode = response.getResponseBody().getErrorCode();
        String respMsg = response.getResponseBody().getErrorMsg();
        //解密应答报文
        SealedData sealedData = new SealedData();
        sealedData.setOriginalData(response.getResponseBody().getSealDataType().getOriginalData()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getOriginalData()));
        sealedData.setSignedData(response.getResponseBody().getSealDataType().getSignedData()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getSignedData()));
        sealedData.setEncryptedData(response.getResponseBody().getSealDataType().getEncryptedData()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getEncryptedData()));
        sealedData.setDigitalEnvelope(response.getResponseBody().getSealDataType().getDigitalEnvelope()==null?null:PKIUtil.utf8String2ByteWithBase64(response.getResponseBody().getSealDataType().getDigitalEnvelope()));
        Mpf mpf = genMpf(fetureCode , membercode);
        UnsealedData unsealedData = null;

        try {

            ICryptoService service = CryptoServiceFactory.createCryptoService();
            unsealedData = service.unseal(mpf, sealedData);

            byte[] decryptedData = unsealedData.getDecryptedData();
            String rtnString = "";
            if (null != decryptedData) {
                rtnString = PKIUtil.byte2UTF8String(decryptedData);
            } else {
                rtnString = PKIUtil.byte2UTF8String(sealedData.getOriginalData());
            }
            logger.info("解密后返回报文: " + rtnString);

            Pay2bankOrder respOrder = CCSUtil_Pay.converyToJavaBean(rtnString,Pay2bankOrder.class);

            if(agentCashOrderVo.getOrderId().equals(respOrder.getOrderId())){
                //支付请求成功
                if(respCode.equals("0000")){
                    //P处理中 S成功  F失败
                    agentCashOrderVo.setPaymentStatus("P");
                    agentCashOrderVo.setPaymentMsg("银行处理中");
                }else{
                    agentCashOrderVo.setPaymentStatus("F");
                    agentCashOrderVo.setPaymentMsg(respMsg);
                }

                agentCashMapper.updateAgentCashOrderByPayment(agentCashOrderVo.getPaymentStatus(),agentCashOrderVo.getPaymentMsg(),agentCashOrderVo.getOrderId());
            }
        } catch (CryptoException e) {
            logger.error("解密失败：",e);
            agentCashOrderVo.setPaymentMsg("解密失败，请稍后发起查询");
            //P处理中 S成功  F失败
            agentCashOrderVo.setPaymentStatus("P");
            //解密失败，需重新发起查询更新状态
            agentCashMapper.updateAgentCashOrderByPayment(agentCashOrderVo.getPaymentStatus(),agentCashOrderVo.getPaymentMsg(),agentCashOrderVo.getOrderId());
        }
        //将订单加入查询队列
        QueryPaymentQueue.set(agentCashOrderVo);
    }

    private void paymentByDetail(GrantDetailVo detail) throws Exception {
        String version = configUtil.getConfigValue("payment","version");        //接口版本
        String membercode = configUtil.getConfigValue("payment","merchant_id"); //商户号
        String fetureCode = configUtil.getConfigValue("payment","feture_code"); //策略编码
        String encoding = configUtil.getConfigValue("payment","encoding");      //字符编码

        //构建一个订单对象
        Pay2bankOrder orderDto = genDetailOrder(detail);
        String orderXml = CCSUtil_Pay.convertToXml(orderDto, encoding);
        logger.info("请求明文报文: " + orderXml);
        //获取原始报文
        String originalStr = orderXml;
        //加签、加密
        Mpf mpf = genMpf(fetureCode , membercode);
        SealedData sealedData = null;
        try {
            ICryptoService service = CryptoServiceFactory.createCryptoService();
            sealedData = service.seal(mpf, originalStr.getBytes(encoding));
        } catch (CryptoException e) {
            logger.error(e);
        } catch (UnsupportedEncodingException e) {
            logger.error(e);
        }
        Pay2bankRequest request = CCSUtil_Pay.genRequest(membercode , version);
        byte[] nullbyte = {};
        byte[] byteOri = sealedData.getOriginalData() == null ? nullbyte : sealedData.getOriginalData();
        byte[] byteEnc = sealedData.getEncryptedData() == null ? nullbyte : sealedData.getEncryptedData();
        byte[] byteEnv = sealedData.getDigitalEnvelope() == null ? nullbyte : sealedData.getDigitalEnvelope();
        byte[] byteSig = sealedData.getSignedData() == null ? nullbyte : sealedData.getSignedData();
        request.getRequestBody().getSealDataType().setOriginalData(PKIUtil.byte2UTF8StringWithBase64(byteOri));
        //获取加签报文
        request.getRequestBody().getSealDataType().setSignedData(PKIUtil.byte2UTF8StringWithBase64(byteSig));
        //获取加密报文
        request.getRequestBody().getSealDataType().setEncryptedData(PKIUtil.byte2UTF8StringWithBase64(byteEnc));
        //数字信封
        request.getRequestBody().getSealDataType().setDigitalEnvelope(PKIUtil.byte2UTF8StringWithBase64(byteEnv));

        //请求报文
        String requestXml = CCSUtil_Pay.convertToXml(request, encoding);
        logger.info("请求加密报文: " + requestXml);

        String sealMsg = invokeCSSCollection(requestXml.trim(), encoding);

        updateDetail(detail, sealMsg, fetureCode , membercode);
    }

    private void paymentByCash(AgentCashOrderVo agentCashOrderVo) throws Exception {
        String version = configUtil.getConfigValue("payment","version");        //接口版本
        String membercode = configUtil.getConfigValue("payment","merchant_id"); //商户号
        String fetureCode = configUtil.getConfigValue("payment","feture_code"); //策略编码
        String encoding = configUtil.getConfigValue("payment","encoding");      //字符编码

        //构建一个订单对象
        Pay2bankOrder orderDto = genCashOrder(agentCashOrderVo);
        String orderXml = CCSUtil_Pay.convertToXml(orderDto, encoding);
        logger.info("请求明文报文: " + orderXml);
        //获取原始报文
        String originalStr = orderXml;
        //加签、加密
        Mpf mpf = genMpf(fetureCode , membercode);
        SealedData sealedData = null;
        try {
            ICryptoService service = CryptoServiceFactory.createCryptoService();
            sealedData = service.seal(mpf, originalStr.getBytes(encoding));
        } catch (CryptoException e) {
            logger.error(e);
        } catch (UnsupportedEncodingException e) {
            logger.error(e);
        }
        Pay2bankRequest request = CCSUtil_Pay.genRequest(membercode , version);
        byte[] nullbyte = {};
        byte[] byteOri = sealedData.getOriginalData() == null ? nullbyte : sealedData.getOriginalData();
        byte[] byteEnc = sealedData.getEncryptedData() == null ? nullbyte : sealedData.getEncryptedData();
        byte[] byteEnv = sealedData.getDigitalEnvelope() == null ? nullbyte : sealedData.getDigitalEnvelope();
        byte[] byteSig = sealedData.getSignedData() == null ? nullbyte : sealedData.getSignedData();
        request.getRequestBody().getSealDataType().setOriginalData(PKIUtil.byte2UTF8StringWithBase64(byteOri));
        //获取加签报文
        request.getRequestBody().getSealDataType().setSignedData(PKIUtil.byte2UTF8StringWithBase64(byteSig));
        //获取加密报文
        request.getRequestBody().getSealDataType().setEncryptedData(PKIUtil.byte2UTF8StringWithBase64(byteEnc));
        //数字信封
        request.getRequestBody().getSealDataType().setDigitalEnvelope(PKIUtil.byte2UTF8StringWithBase64(byteEnv));

        //请求报文
        String requestXml = CCSUtil_Pay.convertToXml(request, encoding);
        logger.info("请求加密报文: " + requestXml);

        String sealMsg = invokeCSSCollection(requestXml.trim(), encoding);

        updateCash(agentCashOrderVo, sealMsg, fetureCode , membercode);
    }

    /**
     * 接收第三方支付实时应答
     * @param requestXml
     * @return
     * @throws Exception
     */
    private String invokeCSSCollection(String requestXml, String encoding) throws Exception {
        String url = configUtil.getConfigValue("payment","pay_url");            //服务端URL

        //初始化HttpClient
        HttpClient client = new HttpClient();
        PostMethod method = new PostMethod(url);
        SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
        sslContext.init(null, null, null);
        SSLContext.setDefault(sslContext);
        //请求服务端
//		InputStream in_withcode = new ByteArrayInputStream(requestXml.getBytes(encoding));
//		method.setRequestBody(in_withcode);
        // url的连接等待超时时间设置
        client.getHttpConnectionManager().getParams().setConnectionTimeout(20000);

        // 读取数据超时时间设置
        client.getHttpConnectionManager().getParams().setSoTimeout(30000);
        method.setRequestEntity(new StringRequestEntity(requestXml, "text/html", "utf-8"));
        client.executeMethod(method);

        //打印服务器返回的状态
        logger.info("应答状态："+method.getStatusLine());

        //打印返回的信息
        InputStream stream = method.getResponseBodyAsStream();
        BufferedReader br = new BufferedReader(new InputStreamReader(stream,encoding));
        StringBuffer buf = new StringBuffer();
        String line;
        while (null != (line = br.readLine())) {
            buf.append(line).append("\n");
        }
        //释放连接
        method.releaseConnection();
        return buf.toString();
    }

    private Mpf genMpf(String fetureCode, String membercode) {
        Mpf mpf = new Mpf();
        mpf.setFeatureCode(fetureCode);
        mpf.setMemberCode(membercode);
        return mpf;
    }

    private Pay2bankOrder genDetailOrder(GrantDetailVo detail){
        Pay2bankOrder order = new Pay2bankOrder();
        //商家订单号 必填
        order.setOrderId(detail.getId());
        //金额（分） 必填
        //因为已经将单位转换成了分，不存在小数位，直接舍弃小数点
        BigDecimal amount = detail.getPayAmount().multiply(new BigDecimal("100"));
        order.setAmount(amount.setScale(0, BigDecimal.ROUND_DOWN).toString());
        //银行名称 必填
        order.setBankName(detail.getPayeeAccountBankName());
        //开户行  非必填
//        order.setBranchName("城东支行");
        //收款人姓名  必填
        order.setCreditName(detail.getPayeeName());
        //收款人手机号  非必填
        order.setMobile(detail.getPayeeMobile());
        //银行卡号 必填
        order.setBankAcctId(detail.getPayeeAccount());
//		//省份城市 非必填
//		order.setProvince("江苏");
//		order.setCity("南京");
        //备注 非必填
//        order.setRemark("模拟交易成功");//模拟交易成功  模拟交易失败   模拟交易
        //手续费作用方：0收款方付费1付款方付费  非必填 默认1
//        order.setFeeAction("1");
        return order;
    }

    private Pay2bankOrder genCashOrder(AgentCashOrderVo cash){
        Pay2bankOrder order = new Pay2bankOrder();
        //商家订单号 必填
        order.setOrderId(cash.getOrderId());
        //金额（分） 必填
        //因为已经将单位转换成了分，不存在小数位，直接舍弃小数点
        BigDecimal amount = cash.getTheAmount().multiply(new BigDecimal("100"));
        order.setAmount(amount.setScale(0, BigDecimal.ROUND_DOWN).toString());
        //银行名称 必填
        order.setBankName(cash.getBankName());
        //开户行  非必填
//        order.setBranchName("城东支行");
        //收款人姓名  必填
        order.setCreditName(cash.getAccountName());
        //收款人手机号  非必填
        order.setMobile(cash.getMobile());
        //银行卡号 必填
        order.setBankAcctId(cash.getBankAccount());
//		//省份城市 非必填
//		order.setProvince("江苏");
//		order.setCity("南京");
        //备注 非必填
//        order.setRemark("模拟交易成功");//模拟交易成功  模拟交易失败   模拟交易
        //手续费作用方：0收款方付费1付款方付费  非必填 默认1
//        order.setFeeAction("1");
        return order;
    }

    /*
     汇付宝支付
    @Override
    public int paymentSellerProvide(String orderId) {
        List<ProvideDetail> details = sellerOrderMapper.queryDetailByOrderId(orderId);


        String isPayment = configUtil.getConfigValue("payment","is_payment");    //支付开关

        //支付接口已关闭
        if("off".equals(isPayment)){
            return 9;
        }

        String merchant = configUtil.getConfigValue("payment","merchant_id");    //商户ID
        String key = configUtil.getConfigValue("payment","key");                 //签名密钥
        String version = configUtil.getConfigValue("payment","version");         //当前接口版本号
        String notify_url = configUtil.getConfigValue("payment","seller_returnUrl");    //异步通知地址
        String DesKey = configUtil.getConfigValue("payment","DesKey");           //密钥
        //请求地址
        String url = configUtil.getConfigValue("payment","payUrl");              //小额支付地址


        批付到银行帐户格式:
        “商户流水号^银行编号^对公对私^收款人帐号^收款人姓名^付款金额^付款理由^
        省份^城市^收款支行名称”来组织数据，每条整数据间用“|”符号分隔，
        商户流水号长度最长20字符。省市格式请严格按照省市查询接口中的说明填写。

        注：整理好信息之后，需要对此数据进行3DES加密，,

        BigDecimal amt = new BigDecimal(0);

        StringBuilder batchPaymentStr = new StringBuilder("");

        for(ProvideDetail pd : details){
            //付款明细组装
            batchPaymentStr.append(pd.getId());  //流水号
            batchPaymentStr.append("^");
            //银行编号
            batchPaymentStr.append(220);       //220           configUtil.getCardBinByBankName(pd.getPayeeAccountBankName())
            batchPaymentStr.append("^");
            batchPaymentStr.append("1");  //对私：0  对公 1
            batchPaymentStr.append("^");
            batchPaymentStr.append(pd.getPayeeAccount());  //收款人账号
            batchPaymentStr.append("^");
            batchPaymentStr.append(pd.getPayeeName());  //收款人姓名
            batchPaymentStr.append("^");
            batchPaymentStr.append(pd.getPayAmount());  //付款金额
            batchPaymentStr.append("^");
            batchPaymentStr.append(pd.getPayeeRemark());  //付款理由
            batchPaymentStr.append("^");
            batchPaymentStr.append("湖南省");  //省份
            batchPaymentStr.append("^");
            batchPaymentStr.append("常德市");  //城市
            batchPaymentStr.append("^");
            batchPaymentStr.append(pd.getPayeeAccountBankName());  //收款支行名称
            batchPaymentStr.append("|");

            //累加付款金额
            amt = amt.add(pd.getPayAmount());
        }

        String paymentStr = batchPaymentStr.substring(0,batchPaymentStr.length()-1);

        //请求参数
        String batch_no = orderId;    //批量付款订单号
        String batch_amt = amt.toString();       //付款总金额
        String batch_num = details.size()+"";   //该次付款总笔数
        //String detail_data = "A123456^2^0^6217000010100164865^张三^0.01^商户付款^北京^北京市^建设银行";           //批付到银行帐户格式
        String ext_param1 = "";                //商户自定义
        String sign = "";                   //签名结果
        //组织签名串
        StringBuilder sign_sb = new StringBuilder();
        sign_sb.append("agent_id").append("=").append(merchant)
                .append("&").append("batch_amt").append("=").append(batch_amt)
                .append("&").append("batch_no").append("=").append(batch_no)
                .append("&").append("batch_num").append("=").append(batch_num)
                .append("&").append("detail_data").append("=").append(paymentStr)
                .append("&").append("ext_param1").append("=").append(ext_param1)
                .append("&").append("key").append("=").append(key)
                .append("&").append("notify_url").append("=").append(notify_url)
                .append("&").append("version").append("=").append(version);
        logger.info("签名参数："+sign_sb.toString().toLowerCase());
        sign = SmallTools.MD5en(sign_sb.toString().toLowerCase());
        logger.info("签名结果："+sign);
        //3DES加密detail_data
        String detailData = Des.Encrypt3Des(paymentStr, DesKey,"ToHex16");
        //请求参数
        StringBuilder requestParams = new StringBuilder();
        requestParams.append("version") .append("=").append(version)      .append("&")
                .append("agent_id")     .append("=").append(merchant)     .append("&")
                .append("batch_no")     .append("=").append(batch_no)     .append("&")
                .append("batch_amt")    .append("=").append(batch_amt)    .append("&")
                .append("batch_num")    .append("=").append(batch_num)	.append("&")
                .append("detail_data")  .append("=").append(detailData)	.append("&")
                .append("notify_url")   .append("=").append(notify_url)	.append("&")
                .append("ext_param1")   .append("=").append(ext_param1)	.append("&")
                .append("sign")          .append("=").append(sign);

        logger.info("请求第三方支付中："+requestParams.toString());

        String res = HttpUtil.sendPost(url,requestParams.toString());

        logger.info("请求结束：" + res);

        if(res == null || res.equals("")){
            logger.error("第三方支付异常....");
            return 1;
        }

        Map<String, String> resMap = HttpUtil.getMsg(res);

        return 0;
    }

    @Override
    public void updateDetail(String detailData){
        //解析详情
        //多笔详情以|间隔
        String [] details = detailData.split("\\|");

        for(String detail_ : details){
            //单笔详情
            //detail_data=20170713213543213514^6230521000000000005171^张三^0.01^S^
            String [] detail = detail_.split("\\^");

            String orderId = detail[0];
            String status = detail[4];

            if(status.equals("S")){
                //支付成功
                sellerOrderMapper.updateDetail(1,"支付成功",orderId);
            }else{
                //支付失败：
                //目前第三方支付没有返回失败原因
                sellerOrderMapper.updateDetail(2,"支付失败",orderId);
            }
        }
    }



    @Override
    public int paymentAgentCashOrder(String orderId){
        AgentCashOrderVo order = orderMapper.queryAgentCashOrderByOrderId(orderId);


        String isPayment = configUtil.getConfigValue("payment","is_payment");    //支付开关

        //支付接口已关闭
        if("off".equals(isPayment)){
            return 9;
        }

        String merchant = configUtil.getConfigValue("payment","merchant_id");    //商户ID
        String key = configUtil.getConfigValue("payment","key");                 //签名密钥
        String version = configUtil.getConfigValue("payment","version");         //当前接口版本号
        String notify_url = configUtil.getConfigValue("payment","agent_returnUrl");    //异步通知地址
        String DesKey = configUtil.getConfigValue("payment","DesKey");           //密钥
        //请求地址
        String url = configUtil.getConfigValue("payment","payUrl");              //小额支付地址


//        批付到银行帐户格式:
//        “商户流水号^银行编号^对公对私^收款人帐号^收款人姓名^付款金额^付款理由^
//        省份^城市^收款支行名称”来组织数据，每条整数据间用“|”符号分隔，
//        商户流水号长度最长20字符。省市格式请严格按照省市查询接口中的说明填写。
//
//        注：整理好信息之后，需要对此数据进行3DES加密，,


        StringBuilder paymentStr = new StringBuilder("");

        //付款明细组装
        paymentStr.append(order.getOrderCode());  //流水号
        paymentStr.append("^");
        //银行编号
        paymentStr.append(
                configUtil.getCardBinByBankName(order.getBankName()));
        paymentStr.append("^");
        paymentStr.append("0");  //对私：0  对公 1
        paymentStr.append("^");
        paymentStr.append(order.getBankAccount());  //收款人账号
        paymentStr.append("^");
        paymentStr.append(order.getAccountName());  //收款人姓名
        paymentStr.append("^");
        paymentStr.append(order.getCashAmount());  //付款金额
        paymentStr.append("^");
        paymentStr.append("");  //付款理由
        paymentStr.append("^");
        paymentStr.append("");  //省份
        paymentStr.append("^");
        paymentStr.append("");  //城市
        paymentStr.append("^");
        paymentStr.append("");  //收款支行名称
        paymentStr.append("|");

        //请求参数
        String batch_no = orderId;    //批量付款订单号
        String batch_amt = order.getCashAmount().toString();       //付款总金额
        String batch_num = "1";   //该次付款总笔数
        //String detail_data = "A123456^2^0^6217000010100164865^张三^0.01^商户付款^北京^北京市^建设银行";           //批付到银行帐户格式
        String ext_param1 = "";                //商户自定义
        String sign = "";                   //签名结果
        //组织签名串
        StringBuilder sign_sb = new StringBuilder();
        sign_sb.append("agent_id").append("=").append(merchant)
                .append("&").append("batch_amt").append("=").append(batch_amt)
                .append("&").append("batch_no").append("=").append(batch_no)
                .append("&").append("batch_num").append("=").append(batch_num)
                .append("&").append("detail_data").append("=").append(paymentStr)
                .append("&").append("ext_param1").append("=").append(ext_param1)
                .append("&").append("key").append("=").append(key)
                .append("&").append("notify_url").append("=").append(notify_url)
                .append("&").append("version").append("=").append(version);
        logger.info("签名参数："+sign_sb.toString().toLowerCase());
        sign = SmallTools.MD5en(sign_sb.toString().toLowerCase());
        logger.info("签名结果："+sign);
        //3DES加密detail_data
        String detailData = Des.Encrypt3Des(paymentStr.toString(), DesKey,"ToHex16");
        //请求参数
        StringBuilder requestParams = new StringBuilder();
        requestParams.append("version") .append("=").append(version)      .append("&")
                .append("agent_id")     .append("=").append(merchant)     .append("&")
                .append("batch_no")     .append("=").append(batch_no)     .append("&")
                .append("batch_amt")    .append("=").append(batch_amt)    .append("&")
                .append("batch_num")    .append("=").append(batch_num)	.append("&")
                .append("detail_data")  .append("=").append(detailData)	.append("&")
                .append("notify_url")   .append("=").append(notify_url)	.append("&")
                .append("ext_param1")   .append("=").append(ext_param1)	.append("&")
                .append("sign")          .append("=").append(sign);

        logger.info("请求第三方支付中："+requestParams.toString());

        String res = HttpUtil.sendPost(url,requestParams.toString());

        logger.info("请求结束：" + res);

        if(res == null || res.equals("")){
            logger.error("第三方支付异常....");
            return 1;
        }

        Map<String, String> resMap = HttpUtil.getMsg(res);

        return 0;
    }


    @Override
    public void updateAgentCash(String orderId,String status){
        AgentCashOrderVo vo = new AgentCashOrderVo();

        vo.setOrderId(orderId);

        根据第三方支付通知结果修改订单
        if(status.equals("S")){
            vo.setOrderType(1);
        }else{
            vo.setOrderType(2);
        }

       // orderMapper.updateAgentCashOrder(vo);
    }

 */
}
